import Config from '@/config/Config'

import JWT from 'jsonwebtoken'

import { AuthFailed, Forbidden } from '@/core/HttpException'
import { Account } from '@/common/typings/account'
import { Menu } from '@/common/typings/menu'
import { Models } from '@/common/typings/modle'
import { command } from '@/server/mysql'
import { Role } from '@/common/typings/role'
import { selectDb } from '@/server/redis'
import redis from '@/server/redis/redis'
import { getTreeByList } from '@/common/utils/utils'
import TokenInfo = Account.TokenInfo

// userId

type Uid = number

// 权限id
type Scope = string

export function generateToken(tokenInfo: TokenInfo, scope: Scope) {
  const secretKey = Config.SECURITY.SECRET_KEY
  const expiresIn = Config.SECURITY.EXPIRES_IN
  const token = JWT.sign(
    {
      tokenInfo,
      scope,
    },
    secretKey,
    {
      expiresIn,
    },
  )
  return token
}

/**
 * 获取用户权限
 * @param decode
 * @returns
 */
export function getUserPermission(decode: Account.Decode): Promise<Menu.Menu[]> {
  const { scope } = decode
  return new Promise(async (resolve, reject) => {
    let res: Models.Result
    try {
      resolve([])
    } catch (error) {
      console.log(error)
      reject()
    }
  })
}
/**
 * 获取所有角色的权限列表
 * @returns
 */
export function getAllRolePermission(): Promise<Role.Role[]> {
  return new Promise(async (resolve, reject) => {
    let res: Models.Result
    try {
      resolve([])
    } catch (error) {
      console.log(error)
      reject()
    }
  })
}

/**
 * 更新redis里的角色
 */
export function updateRedisRole() {
  getAllRolePermission().then((list) => {
    list.forEach((res) => {
      if (res.menuList.length > 0) {
        updateRoles(
          (res.id || '').toString(),
          new Map([
            ['id', res.id.toString()],
            ['parentId', res.parentId.toString()],
            ['permissions', res.menuList.map((item: { permission: string }) => item.permission).join(',')],
          ]),
        )
      }
    })
  })
}

/**
 * 更新权限
 * @param roleId
 * @param obj
 * @returns
 */
export function updateRoles(roleId: string, obj: Map<string, string>): Promise<Models.Result> {
  return new Promise((resolve) => {
    selectDb(Config.REDIS_DB_NAME.ROLE).then(async () => {
      await redis.del(roleId)
      redis.hmset(roleId, obj).then((res) => {
        const result: Models.Result = {
          msg: 'ok',
          state: 1,
          results: res,
          fields: [],
        }
        resolve(result)
      })
    })
  })
}

/**
 * 校验用户权限
 * @param decode
 * @returns
 */
export function getRedisUserPermission(decode: Account.Decode): Promise<string[]> {
  const { scope } = decode
  return new Promise(async (resolve) => {
    selectDb(Config.REDIS_DB_NAME.ROLE).then(() => {
      redis.keys('*').then(async (res) => {
        Promise.all(res.map((item) => redis.hgetall(item))).then((result) => {
          const allRoleList = result.map((item) => {
            return {
              ...item,
              id: Number(item.id),
              parentId: Number(item.parentId),
            }
          })
          const roleTree = getTreeByList(allRoleList, 0)
          // 过滤, 获取当前角色及当前角色的祖先角色的所有记录
          const roleList: Models.TreeNode[] = []
          const each = (list: Models.TreeNode[], nodeId: number) => {
            const arr = list.filter((item) => item.id === nodeId)
            if (arr.length) {
              roleList.push(...arr)
              each(list, arr[0].parentId)
            }
          }
          const roleIds = scope.split(',')
          roleIds.forEach((roleId) => {
            each(roleTree, Number(roleId))
          })

          // 当前角色有权限的所有权限.
          let permissionList: string[] = []
          const merge = (list: Models.TreeNode[]) => {
            list.forEach((item) => {
              permissionList = [...new Set([...permissionList, ...item.permissions.split(',')])]
              if (item.children) {
                merge(item.children)
              }
            })
          }
          // 合并当前角色和当前角色的祖先角色的所有菜单
          merge(roleTree)
          resolve(permissionList)
        })
      })
    })
  })
}
